/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.ces4.produccion.jpa.controllers;

import co.com.ces4.produccion.jpa.controllers.exceptions.IllegalOrphanException;
import co.com.ces4.produccion.jpa.controllers.exceptions.NonexistentEntityException;
import co.com.ces4.produccion.jpa.controllers.exceptions.PreexistingEntityException;
import co.com.ces4.produccion.jpa.entities.OrdenProduccion;
import co.com.ces4.produccion.jpa.entities.OrdenProduccionPK;
import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import co.com.ces4.produccion.jpa.entities.Usuario;
import co.com.ces4.produccion.jpa.entities.SolicitudProduccion;
import co.com.ces4.produccion.jpa.entities.DetalleOrdenProduccion;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.TemporalType;

/**
 *
 * @author usuario
 */
public class OrdenProduccionJpaController implements Serializable {

    public OrdenProduccionJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(OrdenProduccion ordenProduccion) throws PreexistingEntityException, Exception {
        if (ordenProduccion.getOrdenProduccionPK() == null) {
            ordenProduccion.setOrdenProduccionPK(new OrdenProduccionPK());
        }
        if (ordenProduccion.getDetalleOrdenProduccionList() == null) {
            ordenProduccion.setDetalleOrdenProduccionList(new ArrayList<DetalleOrdenProduccion>());
        }
        ordenProduccion.getOrdenProduccionPK().setNmsolicitudProduccion(ordenProduccion.getSolicitudProduccion().getNmid());
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario dsusuario = ordenProduccion.getDsusuario();
            if (dsusuario != null) {
                dsusuario = em.getReference(dsusuario.getClass(), dsusuario.getDsid());
                ordenProduccion.setDsusuario(dsusuario);
            }
            SolicitudProduccion solicitudProduccion = ordenProduccion.getSolicitudProduccion();
            if (solicitudProduccion != null) {
                solicitudProduccion = em.getReference(solicitudProduccion.getClass(), solicitudProduccion.getNmid());
                ordenProduccion.setSolicitudProduccion(solicitudProduccion);
            }
            List<DetalleOrdenProduccion> attachedDetalleOrdenProduccionList = new ArrayList<DetalleOrdenProduccion>();
            for (DetalleOrdenProduccion detalleOrdenProduccionListDetalleOrdenProduccionToAttach : ordenProduccion.getDetalleOrdenProduccionList()) {
                detalleOrdenProduccionListDetalleOrdenProduccionToAttach = em.getReference(detalleOrdenProduccionListDetalleOrdenProduccionToAttach.getClass(), detalleOrdenProduccionListDetalleOrdenProduccionToAttach.getDetalleOrdenProduccionPK());
                attachedDetalleOrdenProduccionList.add(detalleOrdenProduccionListDetalleOrdenProduccionToAttach);
            }
            ordenProduccion.setDetalleOrdenProduccionList(attachedDetalleOrdenProduccionList);
            em.persist(ordenProduccion);
            if (dsusuario != null) {
                dsusuario.getOrdenProduccionList().add(ordenProduccion);
                dsusuario = em.merge(dsusuario);
            }
            if (solicitudProduccion != null) {
                solicitudProduccion.getOrdenProduccionList().add(ordenProduccion);
                solicitudProduccion = em.merge(solicitudProduccion);
            }
            for (DetalleOrdenProduccion detalleOrdenProduccionListDetalleOrdenProduccion : ordenProduccion.getDetalleOrdenProduccionList()) {
                OrdenProduccion oldOrdenProduccionOfDetalleOrdenProduccionListDetalleOrdenProduccion = detalleOrdenProduccionListDetalleOrdenProduccion.getOrdenProduccion();
                detalleOrdenProduccionListDetalleOrdenProduccion.setOrdenProduccion(ordenProduccion);
                detalleOrdenProduccionListDetalleOrdenProduccion = em.merge(detalleOrdenProduccionListDetalleOrdenProduccion);
                if (oldOrdenProduccionOfDetalleOrdenProduccionListDetalleOrdenProduccion != null) {
                    oldOrdenProduccionOfDetalleOrdenProduccionListDetalleOrdenProduccion.getDetalleOrdenProduccionList().remove(detalleOrdenProduccionListDetalleOrdenProduccion);
                    oldOrdenProduccionOfDetalleOrdenProduccionListDetalleOrdenProduccion = em.merge(oldOrdenProduccionOfDetalleOrdenProduccionListDetalleOrdenProduccion);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findOrdenProduccion(ordenProduccion.getOrdenProduccionPK()) != null) {
                throw new PreexistingEntityException("OrdenProduccion " + ordenProduccion + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(OrdenProduccion ordenProduccion) throws IllegalOrphanException, NonexistentEntityException, Exception {
        ordenProduccion.getOrdenProduccionPK().setNmsolicitudProduccion(ordenProduccion.getSolicitudProduccion().getNmid());
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            OrdenProduccion persistentOrdenProduccion = em.find(OrdenProduccion.class, ordenProduccion.getOrdenProduccionPK());
            Usuario dsusuarioOld = persistentOrdenProduccion.getDsusuario();
            Usuario dsusuarioNew = ordenProduccion.getDsusuario();
            SolicitudProduccion solicitudProduccionOld = persistentOrdenProduccion.getSolicitudProduccion();
            SolicitudProduccion solicitudProduccionNew = ordenProduccion.getSolicitudProduccion();
            List<DetalleOrdenProduccion> detalleOrdenProduccionListOld = persistentOrdenProduccion.getDetalleOrdenProduccionList();
            List<DetalleOrdenProduccion> detalleOrdenProduccionListNew = ordenProduccion.getDetalleOrdenProduccionList();
            List<String> illegalOrphanMessages = null;
            for (DetalleOrdenProduccion detalleOrdenProduccionListOldDetalleOrdenProduccion : detalleOrdenProduccionListOld) {
                if (!detalleOrdenProduccionListNew.contains(detalleOrdenProduccionListOldDetalleOrdenProduccion)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain DetalleOrdenProduccion " + detalleOrdenProduccionListOldDetalleOrdenProduccion + " since its ordenProduccion field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (dsusuarioNew != null) {
                dsusuarioNew = em.getReference(dsusuarioNew.getClass(), dsusuarioNew.getDsid());
                ordenProduccion.setDsusuario(dsusuarioNew);
            }
            if (solicitudProduccionNew != null) {
                solicitudProduccionNew = em.getReference(solicitudProduccionNew.getClass(), solicitudProduccionNew.getNmid());
                ordenProduccion.setSolicitudProduccion(solicitudProduccionNew);
            }
            List<DetalleOrdenProduccion> attachedDetalleOrdenProduccionListNew = new ArrayList<DetalleOrdenProduccion>();
            for (DetalleOrdenProduccion detalleOrdenProduccionListNewDetalleOrdenProduccionToAttach : detalleOrdenProduccionListNew) {
                detalleOrdenProduccionListNewDetalleOrdenProduccionToAttach = em.getReference(detalleOrdenProduccionListNewDetalleOrdenProduccionToAttach.getClass(), detalleOrdenProduccionListNewDetalleOrdenProduccionToAttach.getDetalleOrdenProduccionPK());
                attachedDetalleOrdenProduccionListNew.add(detalleOrdenProduccionListNewDetalleOrdenProduccionToAttach);
            }
            detalleOrdenProduccionListNew = attachedDetalleOrdenProduccionListNew;
            ordenProduccion.setDetalleOrdenProduccionList(detalleOrdenProduccionListNew);
            ordenProduccion = em.merge(ordenProduccion);
            if (dsusuarioOld != null && !dsusuarioOld.equals(dsusuarioNew)) {
                dsusuarioOld.getOrdenProduccionList().remove(ordenProduccion);
                dsusuarioOld = em.merge(dsusuarioOld);
            }
            if (dsusuarioNew != null && !dsusuarioNew.equals(dsusuarioOld)) {
                dsusuarioNew.getOrdenProduccionList().add(ordenProduccion);
                dsusuarioNew = em.merge(dsusuarioNew);
            }
            if (solicitudProduccionOld != null && !solicitudProduccionOld.equals(solicitudProduccionNew)) {
                solicitudProduccionOld.getOrdenProduccionList().remove(ordenProduccion);
                solicitudProduccionOld = em.merge(solicitudProduccionOld);
            }
            if (solicitudProduccionNew != null && !solicitudProduccionNew.equals(solicitudProduccionOld)) {
                solicitudProduccionNew.getOrdenProduccionList().add(ordenProduccion);
                solicitudProduccionNew = em.merge(solicitudProduccionNew);
            }
            for (DetalleOrdenProduccion detalleOrdenProduccionListNewDetalleOrdenProduccion : detalleOrdenProduccionListNew) {
                if (!detalleOrdenProduccionListOld.contains(detalleOrdenProduccionListNewDetalleOrdenProduccion)) {
                    OrdenProduccion oldOrdenProduccionOfDetalleOrdenProduccionListNewDetalleOrdenProduccion = detalleOrdenProduccionListNewDetalleOrdenProduccion.getOrdenProduccion();
                    detalleOrdenProduccionListNewDetalleOrdenProduccion.setOrdenProduccion(ordenProduccion);
                    detalleOrdenProduccionListNewDetalleOrdenProduccion = em.merge(detalleOrdenProduccionListNewDetalleOrdenProduccion);
                    if (oldOrdenProduccionOfDetalleOrdenProduccionListNewDetalleOrdenProduccion != null && !oldOrdenProduccionOfDetalleOrdenProduccionListNewDetalleOrdenProduccion.equals(ordenProduccion)) {
                        oldOrdenProduccionOfDetalleOrdenProduccionListNewDetalleOrdenProduccion.getDetalleOrdenProduccionList().remove(detalleOrdenProduccionListNewDetalleOrdenProduccion);
                        oldOrdenProduccionOfDetalleOrdenProduccionListNewDetalleOrdenProduccion = em.merge(oldOrdenProduccionOfDetalleOrdenProduccionListNewDetalleOrdenProduccion);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                OrdenProduccionPK id = ordenProduccion.getOrdenProduccionPK();
                if (findOrdenProduccion(id) == null) {
                    throw new NonexistentEntityException("The ordenProduccion with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(OrdenProduccionPK id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            OrdenProduccion ordenProduccion;
            try {
                ordenProduccion = em.getReference(OrdenProduccion.class, id);
                ordenProduccion.getOrdenProduccionPK();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The ordenProduccion with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<DetalleOrdenProduccion> detalleOrdenProduccionListOrphanCheck = ordenProduccion.getDetalleOrdenProduccionList();
            for (DetalleOrdenProduccion detalleOrdenProduccionListOrphanCheckDetalleOrdenProduccion : detalleOrdenProduccionListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This OrdenProduccion (" + ordenProduccion + ") cannot be destroyed since the DetalleOrdenProduccion " + detalleOrdenProduccionListOrphanCheckDetalleOrdenProduccion + " in its detalleOrdenProduccionList field has a non-nullable ordenProduccion field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Usuario dsusuario = ordenProduccion.getDsusuario();
            if (dsusuario != null) {
                dsusuario.getOrdenProduccionList().remove(ordenProduccion);
                dsusuario = em.merge(dsusuario);
            }
            SolicitudProduccion solicitudProduccion = ordenProduccion.getSolicitudProduccion();
            if (solicitudProduccion != null) {
                solicitudProduccion.getOrdenProduccionList().remove(ordenProduccion);
                solicitudProduccion = em.merge(solicitudProduccion);
            }
            em.remove(ordenProduccion);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<OrdenProduccion> findOrdenProduccionEntities() {
        return findOrdenProduccionEntities(true, -1, -1);
    }

    public List<OrdenProduccion> findOrdenProduccionEntities(int maxResults, int firstResult) {
        return findOrdenProduccionEntities(false, maxResults, firstResult);
    }

    private List<OrdenProduccion> findOrdenProduccionEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(OrdenProduccion.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public OrdenProduccion findOrdenProduccion(OrdenProduccionPK id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(OrdenProduccion.class, id);
        } finally {
            em.close();
        }
    }

    public int getOrdenProduccionCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<OrdenProduccion> rt = cq.from(OrdenProduccion.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

    public List<OrdenProduccion> getOrdenProduccionList(Date fechaInicio, Date fechaFin, SolicitudProduccion solicitudProduccion) {
        EntityManager em = getEntityManager();
        try {
            StringBuilder sb = new StringBuilder("SELECT ordenP FROM OrdenProduccion ordenP WHERE 1=1 ");
            if (fechaInicio != null && fechaFin != null) {
                sb.append("AND (ordenP.fefechaOrden BETWEEN :fechaInicio AND :fechaFin ");
                if (solicitudProduccion != null) {
                    sb.append("AND ordenP.solicitudProduccion.nmid = :NMID");
                }
                sb.append(")");
            }

            Query query = em.createQuery(sb.toString());
            if (fechaInicio != null) {
                query.setParameter("fechaInicio", fechaInicio, TemporalType.DATE);
            }
            if (fechaFin != null) {
                query.setParameter("fechaFin", fechaFin, TemporalType.DATE);
            }

            if (solicitudProduccion != null) {
                query.setParameter("NMID", solicitudProduccion.getNmid());
            }

            List<OrdenProduccion> ordenes = query.getResultList();
            return ordenes;

        } finally {
            em.close();
        }
    }
}
